package com.lin.service.ranges;

import com.lin.common.constant.CommonConstant;
import com.lin.common.constant.CustomerServiceConstant;
import com.lin.common.error.CustomRuntimeException;
import com.lin.common.utils.BeanCopyUtils;
import com.lin.common.utils.DateUtils;
import com.lin.common.utils.RedisSerializableUtils;
import com.lin.controller.req.RangeReqMsg;
import com.lin.dao.RangesMapper;
import com.lin.po.Customer;
import com.lin.po.Ranges;
import com.lin.socketio.dto.Encounter;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class RangesServiceImpl implements RangesService {
    @Autowired
    private RangesMapper rangesMapper;

    @Value("${cs.top.logintime.minute}")
    private Integer minute;

    @Value("${cs.top.ranges.set}")
    private String rangeskey;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${" + CustomerServiceConstant.encounter_topic + "}")
    private String encounterTopic;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public Integer location(RangeReqMsg reqMsg) throws CustomRuntimeException {
        Ranges r = build(reqMsg);
        int i = rangesMapper.updateByPrimaryKeySelective(r);
        if (i == 0) {
            r.setId(Long.parseLong(RedisSerializableUtils.generateForLong(CommonConstant.DEFAULT_LENGTH)));
            i = rangesMapper.insertSelective(r);
        }

        //请求时顺便把新登录的存入redis中
        //redissonClient.getSet(rangeskey).add(new Ranges(r.getCustomerId(), r.getAge(), r.getLongitude(), r.getLongitude()));
        //TODO 触发消息，并把列表推送过去，并在消息后面调用encounter命名空间的socketioclient.event
        Encounter e= BeanCopyUtils.beanCopy(r, Encounter.class);
        rabbitTemplate.convertAndSend(encounterTopic,null,e);
        return i;
    }

    @Override
    public Set<Ranges> listrange(Customer customer) {
        //先从REDIS中获取，超时时间为minute，如果获取未空，则从数据库中获取，数据库中获取为空则为空；
        Set<Ranges> set = redissonClient.getSet(rangeskey);
        if (null == set) {
            set = rangesMapper.listTopNminute(minute);
            RSet<Ranges> rset = redissonClient.getSet(rangeskey);
            rset.addAll(set);
            rset.expire(minute, TimeUnit.MINUTES);
        }
        // TODO 需要新增经纬度的距离
        if (set != null) {
            return set.stream().filter(ranges -> Math.abs(customer.getAge() - ranges.getAge()) < 10 && !ranges.getGender().equals(customer.getGender())).collect(Collectors.toSet());
        }
        return set;
    }

    private Ranges build(RangeReqMsg reqMsg) {
        Ranges r = BeanCopyUtils.beanCopy(reqMsg, Ranges.class);
        r.setCreateTime(DateUtils.fullDateFormat());
        r.setUpdateTime(DateUtils.fullDateFormat());
        r.setAge(DateUtils.calculateAge(LocalDate.parse(reqMsg.getBirthday()), LocalDate.now()));
        return r;
    }
}
